/*
 * Copyright (c) 2015. For Intelligent Group.
 */
package com.intelligent.ispc.client.core.modal.grr;

import com.google.common.collect.Lists;
import com.intelligent.ispc.client.utils.SystemConfigUtils;
import com.intelligent.ispc.client.utils.UIConstant;
import com.intelligent.ispc.common.utils.StringUtils;
import com.intelligent.ispc.core.dto.GrrStatisticDataDto;
import com.intelligent.ispc.core.dto.GrrViewDataDto;
import com.intelligent.ispc.core.dto.KeyValueDto;

import javax.swing.table.AbstractTableModel;
import java.util.List;

/**
 * Created by cherry on 16/8/30.
 */
public class ItemDetailTableModel extends AbstractTableModel {

    private String[] columns;
    private List<GrrViewDataDto> sourceData;
    private List<GrrStatisticDataDto> calculatedData;

    private int appraiserCount;
    private int trialCount;
    private int digGrrNum = UIConstant.DEFAULT_GRR_DIGNUM;

    /**
     * ItemDetailTableModel constructor
     */
    public ItemDetailTableModel() {
    }

    /**
     * ItemDetailTableModel constructor
     *
     * @param appraiserCount appraiser count
     * @param trialCount     trial count
     * @param columns        table columns
     */
    public ItemDetailTableModel(int appraiserCount, int trialCount, String[] columns) {

        this.appraiserCount = appraiserCount;
        this.trialCount = trialCount;
        if (columns == null) {
            this.columns = new String[0];
            return;
        }

        this.columns = new String[columns.length];
        System.arraycopy(columns, 0, this.columns, 0, columns.length);

        sourceData = Lists.newArrayList();
        calculatedData = Lists.newArrayList();
    }

    @Override
    public int getRowCount() {
        int rowCount = appraiserCount * (trialCount + 2) + 2;
        return rowCount;
    }

    @Override
    public int getColumnCount() {
        return this.columns == null ? 0 : columns.length;
    }

    @Override
    public String getColumnName(int column) {
        return columns == null ? "" : columns[column];
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {

        int reminder = rowIndex % (trialCount + 2);
        int value = rowIndex / (trialCount + 2);
        int index = value * trialCount + reminder;

        if (calculatedData == null || sourceData == null || calculatedData.isEmpty() || sourceData.isEmpty()) {
            return "";
        }

        //Total mean value
        if (getRowCount() > 2 && rowIndex == getRowCount() - 2) {

            List<KeyValueDto> totalMeanDtos = calculatedData.get(calculatedData.size() - 1).getTotalMeanList();
            switch (columnIndex) {
                case 0:
                    return "";
                case 1:
                    return "Total Mean";
                default:
                    return setItemsColumValue(totalMeanDtos, columnIndex);
            }
        }

        //Total Range Value
        if (getRowCount() > 1 && rowIndex == getRowCount() - 1) {

            List<KeyValueDto> totalRangeDtos = calculatedData.get(calculatedData.size() - 1).getTotalRangList();
            switch (columnIndex) {
                case 0:
                    return "";
                case 1:
                    return "Total Range";
                default:
                    return setItemsColumValue(totalRangeDtos, columnIndex);
            }
        }

        //mean value
        if (reminder == trialCount && calculatedData.size() > value) {

            String mean = calculatedData.get(value).getMean();
            List<KeyValueDto> meanDtos = calculatedData.get(value).getMeanList();
            switch (columnIndex) {
                case 0:
                    return StringUtils.isNumeric(mean) ? ("Avg=" + StringUtils.formatDouble(Double.valueOf(mean), digGrrNum)) : "-";
                case 1:
                    return "Mean";
                default:
                    return setItemsColumValue(meanDtos, columnIndex);
            }
        }

        // range value
        if (reminder == trialCount + 1 && calculatedData.size() > value) {
            String range = calculatedData.get(value).getRang();
            List<KeyValueDto> rangeDtos = calculatedData.get(value).getRangList();
            switch (columnIndex) {
                case 0:
                    return StringUtils.isNumeric(range) ? ("Σ=" + StringUtils.formatDouble(Double.valueOf(range), digGrrNum)) : "-";
                case 1:
                    return "Range";
                default:
                    return setItemsColumValue(rangeDtos, columnIndex);
            }
        }

        // test item value
        for (int i = 0; i < trialCount; i++) {
            if (reminder == i && sourceData.size() > index) {
                GrrViewDataDto grrViewDataDto = sourceData.get(index);
                String operator = grrViewDataDto.getOperator();
                String trial = grrViewDataDto.getTrial();
                List<KeyValueDto> keyValueDtos = grrViewDataDto.getColValueDtoList();
                switch (columnIndex) {
                    case 0:
                        return operator;
                    case 1:
                        return StringUtils.isNumeric(trial) ? trial : "-";
                    default:
                        return setItemsColumValue(keyValueDtos, columnIndex);
                }
            }
        }

        return "";
    }

    /**
     * set item detail model data source
     *
     * @param grrViewDataDtos      grr viewDataDtos data source
     * @param grrStatisticDataDtos grr statisticDataDtos data source
     */
    public void setData(List<GrrViewDataDto> grrViewDataDtos, List<GrrStatisticDataDto> grrStatisticDataDtos) {

        if (sourceData == null || calculatedData == null) {
            return;
        }

        if (grrViewDataDtos == null) {
            sourceData = Lists.newArrayList();
        } else {
            sourceData.clear();
            sourceData.addAll(grrViewDataDtos);
        }

        if (grrStatisticDataDtos == null) {
            calculatedData = Lists.newArrayList();
        } else {
            calculatedData.clear();
            calculatedData.addAll(grrStatisticDataDtos);
        }
        fireTableDataChanged();
    }

    private Object setItemsColumValue(List<KeyValueDto> keyValueDtos, int columnIndex) {

        String returnValue = "";
        if (keyValueDtos != null) {
            for (int i = 0; i < keyValueDtos.size(); i++) {
                if (columns[columnIndex].equals(keyValueDtos.get(i).getKey())) {
                    returnValue = keyValueDtos.get(i).getValue().toString();
                    break;
                }
            }
        }

        if (!StringUtils.isNumeric(returnValue)) {
            returnValue = "-";
        } else {
            returnValue = StringUtils.formatDouble(Double.valueOf(returnValue), digGrrNum) + "";
        }
        return returnValue;
    }

    public int getTrialCount() {
        return trialCount;
    }

    /**
     * init digNum value
     */
    public void initDigGrrNum() {
        digGrrNum = SystemConfigUtils.getInstance().getGrrDigit();
    }
}
